import * as THREE from "three";
//创建场景
const scene = new THREE.Scene();
//创建透视相机 还有
const camera = new THREE.PerspectiveCamera(
  //fov：透视相机视线角度，单位为弧度。例如，fov值为60度时，摄像机视野范围为水平方向90度，垂直方向90度。
  45,
  //aspect：摄像机的宽高比。例如，当宽高比为2时，摄像机宽度为高度的两倍。
  window.innerWidth / window.innerHeight,
  //near：摄像机焦距距离，单位为像素。例如，当near值为0.1时，远近平面距离为100像素
  0.1,
  //far：摄像机裁剪距离，单位为像素。例如，当far值为1000时，超过该距离的物体将不会被渲染。
  1000
);

camera.position.set(0, 1, 8);

//创建立方体
const geometry = new THREE.SphereGeometry(1, 32, 16);
//创建立方体材质

//(顶点着色器)
const vertex = `
  uniform float uTime; 
  varying vec2 vUv;
  void main() {
    vUv = uv;
    vec3 newpro = position ;
    newpro.y +=sin( position.y*(sin(uTime)*5.0) ) ;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(newpro, 1.0);
  }
`;
/**
 * (片元着色器)
 * 片元着色器是逐片元进行处理的，每个片元都会执行一次片元着色器代码。
 * 片元着色器代码可以访问片元的颜色、位置等属性，并对其进行处理。
 * 片元着色器代码的输出是片元的最终颜色。
 * smoothstep() 内置函数。
 * smoothstep(edge1, edge2, x) 接收3个参数，
 * 当 x<=edge1 时返回0.0；
 * 当 x>=edge2 时返回1.0；
 * 当 edge1<x<edge2 时返回平滑插值的数值
 */
const fragment = `
varying vec2 vUv;

void main() {
  float strength = smoothstep(0.2, 0.8, vUv.x);
  vec3 color = vec3(strength);
  gl_FragColor = vec4(color, 1.0);
}

`;

const material = new THREE.ShaderMaterial({
  /**
   * 在 ShaderMaterial 里可以通过 uniforms 从主程序 js 里传入所需的变量，
   * 其在顶点着色器和片元着色器里都能获取到，且对于每个顶点或片元数值统一相同，
   * 注意设置时不是 uTime: 0 这样的格式，后面必须是对象格式 uTime: { value: 0 }，
   * 其他 uniform 变量同理。
   */
  uniforms: {
    uTime: {
      value: 0
    }
  },
  //顶点着色器
  vertexShader: vertex,
  //片元着色器
  fragmentShader: fragment,
  /* 配合抗锯齿 */
  extensions: { derivatives: true },
  /* 线框模式 */
  wireframe: true
});

//网格
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 0.8, 0);
scene.add(mesh);

//渲染器
const renderer = new THREE.WebGLRenderer({
  //抗锯齿
  antialias: true
});
//设置像素比，解决retina屏幕模糊问题
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 1));
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor("#e6fcf5", 1);
document.body.appendChild(renderer.domElement);

//添加网格地面
const GridHelper = new THREE.GridHelper(10, 10);
scene.add(GridHelper);

//动画
let time = 0;
function animate() {
  time += 0.02;
  material.uniforms.uTime.value = time;
  // 请求下一次动画渲染
  requestAnimationFrame(animate);
  // mesh的旋转属性递增
  // mesh.rotation.x += 0.01;
  // mesh.rotation.y += 0.01;
  // 使用渲染器渲染场景
  renderer.render(scene, camera);
}
animate();
